package com.starry.core.web.core.security;

import cn.hutool.core.collection.CollUtil;
import com.starry.core.common.constants.WebFilterOrderEnum;
import com.starry.core.common.domain.R;
import com.starry.core.common.utils.ServletUtils;
import com.starry.core.security.config.SecurityProperties;
import com.starry.core.security.context.SecurityInfoContext;
import com.starry.core.security.domain.BaseUser;
import com.starry.core.web.config.web.WebProperties;
import jakarta.annotation.Resource;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

/**
 * 过滤用户类型
 * 1.后台用户只能访问后台用户相关接口
 * 2.前台用户只能访问前台用户相关接口
 * @author xiaoke
 */
@Order(WebFilterOrderEnum.TENANT_SECURITY_FILTER)
@Component
public class SecurityUserTypeFilter extends OncePerRequestFilter {

    @Resource
    private WebProperties webProperties;

    @Resource
    private SecurityProperties securityProperties;

    private final AntPathMatcher pathMatcher;

    public SecurityUserTypeFilter() {
        this.pathMatcher = new AntPathMatcher();
    }


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        String requestURI = request.getRequestURI();
        BaseUser loginUser = SecurityInfoContext.getLoginUser();

        //loginUser不存在，证明是不需要认证的接口（因为当前过滤器是已经经过校验的）
        if (loginUser == null) {
            doFilter(request, response, chain);
            return;
        }

        // 不需要人认证接口直接放行
        if (isIgnoreUrl(request)) {
            chain.doFilter(request, response);
            return;
        }

        switch (loginUser.getUserType()) {
            case ADMIN:
                if (requestURI.startsWith(webProperties.getAdminApi().getPrefix())) {
                    chain.doFilter(request, response);
                } else {
                    ServletUtils.writeJSON(response, R.fail(HttpStatus.FORBIDDEN.value(), "无权访问"));
                }
                break;
            case MEMBER:
                if (requestURI.startsWith(webProperties.getAppApi().getPrefix())) {
                    chain.doFilter(request, response);
                } else {
                    ServletUtils.writeJSON(response, R.fail(HttpStatus.FORBIDDEN.value(), "无权访问"));
                }
                break;
            default:
                HttpStatus badRequest = HttpStatus.BAD_REQUEST;
                ServletUtils.writeJSON(response, R.fail(badRequest.value(), badRequest.name()));
        }
    }

    private boolean isIgnoreUrl(HttpServletRequest request) {
        // 快速匹配，保证性能
        if (CollUtil.contains(securityProperties.getIgnoreAuthSet(), request.getRequestURI())) {
            return true;
        }
        // 逐个 Ant 路径匹配
        for (String url : securityProperties.getIgnoreAuthSet()) {
            if (pathMatcher.match(url, request.getRequestURI())) {
                return true;
            }
        }
        return false;
    }
}
